package com.inspur.gs.sbssdl.database.rysj.rysj.back.commoncmps;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.inspur.edp.bef.api.services.IBefSessionManager;
import com.inspur.edp.caf.db.dbaccess.DynamicResultRow;
import com.inspur.edp.dxc.spi.components.BaseCustomValidateComponent;
import com.inspur.edp.qdp.bql.api.IBqlExecuter;
import com.inspur.edp.qdp.bql.api.OptionType;
import com.inspur.gs.sbssdl.database.rysj.rysj.back.util.HttpUtil;
import com.inspur.gs.sbssdl.database.rysj.rysj.back.util.SQLUtil;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.runtime.config.BqlBeanUtil;
import io.iec.edp.caf.sysmanager.api.common.TreeFilter;
import io.iec.edp.caf.sysmanager.api.data.org.GSPSysOrg;
import io.iec.edp.caf.sysmanager.api.data.org.SysOrgState;
import io.iec.edp.caf.sysmanager.api.data.org.SysOrgType;
import io.iec.edp.caf.sysmanager.api.data.user.User;
import io.iec.edp.caf.sysmanager.api.data.user.UserState;
import io.iec.edp.caf.sysmanager.api.data.user.UserType;
import io.iec.edp.caf.sysmanager.api.manager.org.SysOrgManager;
import io.iec.edp.caf.sysmanager.api.manager.user.UserLimitManager;
import io.iec.edp.caf.sysmanager.api.manager.user.UserManager;
import lombok.extern.slf4j.Slf4j;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;

@Slf4j
public class SbssDeptAndPeople extends BaseCustomValidateComponent {

    public SbssDeptAndPeople() {
    }

    private IBqlExecuter bqlExecuter;

    private boolean init = false;

    private UserManager userManager;

    private UserLimitManager userLimitManager;

    private SysOrgManager sysOrgManager;

    private GSPSysOrg topOrg;

    private HashMap<String, String> deptpkMap = new HashMap<>();

    public void updateDeptAndPerson() {
        bqlExecuter = BqlBeanUtil.getAppCtx().getBean(IBqlExecuter.class);
        bqlExecuter.getOptions().setOptionType(OptionType.ExecuteSql);
        sysOrgManager = SpringBeanUtils.getBean(SysOrgManager.class);
        userManager = SpringBeanUtils.getBean(UserManager.class);
        userLimitManager = SpringBeanUtils.getBean(UserLimitManager.class);

        SpringBeanUtils.getBean(IBefSessionManager.class).createSession(Duration.ofHours(2));
        try {
            // 获取顶级CODE
            TreeFilter treeFilter = new TreeFilter();
            treeFilter.setName("大连船舶重工集团有限公司");
            // 查询是否有该组织
            List<GSPSysOrg> top = sysOrgManager.getOrgsByFilter(treeFilter);
            if (top.isEmpty()) {
                topOrg = new GSPSysOrg();
                String topVoId = UUID.randomUUID().toString();
                topOrg.setId(topVoId);
                topOrg.setName("大连船舶重工集团有限公司");
                topOrg.setCode("0001");
                topOrg.setNodeType(SysOrgType.org);
                sysOrgManager.addSysOrg(topOrg);
                top = sysOrgManager.getOrgsByFilter(treeFilter);
            }
            topOrg = top.get(0);

            // 1. 获取组织架构
            getDept();

            // 2. 获取人员信息
            String ts = queryLog();
            getPerson(ts);
            // 3. 记录并更新日志
            updateLog();
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        } finally {
            SpringBeanUtils.getBean(IBefSessionManager.class).closeCurrentSession();
        }
        log.info("人员部门同步完成!");
    }

    public void getDept() throws Exception {
        // 获取配置信息
        String selectUrl = "select cfgvalue as CV from SBSS_POST_OUTSEVE where NODE = 'deptUrl' and LABEL = 'url'";
        List<DynamicResultRow> resRows = bqlExecuter.executeSelectStatement(selectUrl, new ArrayList<>());
        if (resRows.isEmpty()) {
            throw new Exception("获取组织架构URL失败!!! 请检查 SBSS_POST_OUTSEVE 表中 NODE = 'deptUrl' 与 LABEL = 'url' 是否存在");
        }
        log.info("开始组织同步!");

        String url = resRows.get(0).get("CV").toString();

        DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00");
        String nowFormat = LocalDateTime.now().format(ofPattern);
        LocalDateTime nowDateTime = LocalDateTime.parse(nowFormat, ofPattern);
        ZonedDateTime zonedDateTime = nowDateTime.atZone(ZoneOffset.ofHours(8)).plusMinutes(1);
        Instant instant = zonedDateTime.toInstant();
        Date nowDate = Date.from(instant);

        for (int inner = 1; inner < 5; inner++) {
            int offset = 0;
            int limit = 500;
            int dataCount = limit;
            HashMap<String, Object> queryParam = new HashMap<>();
            while (dataCount > 0) {
                queryParam.put("offset", offset);
                queryParam.put("limit", limit);
                String respStr = HttpUtil.doGet(url, queryParam);

                ObjectMapper jsonParser = new ObjectMapper();
                JsonNode jsonNode = jsonParser.readTree(respStr);
                JsonNode items = jsonNode.get("data").get("items");
                dataCount = items.size();
                for (JsonNode item : items) {
                    int innercode = item.get("innercode").asInt(4);
                    if (innercode != inner) {
                        continue;
                    }

                    String pkDoc = item.get("pk_deptdoc").asText();
                    String pkftDoc = item.get("pk_fathedept").asText();
                    String name = removeSpecialChars(item.get("deptname").asText());
                    String attribute = item.get("attribute").asText();
                    String code = item.get("deptcode").asText();
                    String deptlistname = item.get("deptlistname").asText();
                    int squence = item.get("squence").asInt(999);

                    // 查询是否有该组织
                    GSPSysOrg gspSysOrg = sysOrgManager.getSysOrg(pkDoc);
                    boolean isNew = false;
                    if (gspSysOrg == null) {
                        gspSysOrg = new GSPSysOrg();
                        gspSysOrg.setId(pkDoc);
                        gspSysOrg.setName(name);
                        gspSysOrg.setNodeType(SysOrgType.dept);
                        gspSysOrg.setCode(code);
                        gspSysOrg.setSortOrder(squence);
                        isNew = true;
                    } else {
                        gspSysOrg.setState(SysOrgState.using);
                        Map<String, String> nameLanguage = gspSysOrg.getNameLanguage();
                        nameLanguage.put("zh-CHS", name);
                    }

                    if (inner == 1) {
                        String attId = deptpkMap.get(attribute);
                        if (attId != null) {
                            gspSysOrg.setParentId(attId);
                            gspSysOrg.setLayer(3);
                        } else {
                            TreeFilter treeFilter = new TreeFilter();
                            treeFilter.setName(attribute);
                            GSPSysOrg topVo;
                            String topVoId;
                            List<GSPSysOrg> orgsByFilter = sysOrgManager.getOrgsByFilter(treeFilter);
                            if (orgsByFilter.isEmpty()) {
                                // 新增虚拟下级部门
                                topVo = new GSPSysOrg();
                                topVoId = UUID.randomUUID().toString();
                                topVo.setId(topVoId);
                                topVo.setName(attribute);
                                topVo.setCode(attribute);
                                topVo.setParentId(topOrg.getId());
                                topVo.setNodeType(SysOrgType.dept);
                                topVo.setLayer(2);
                                GSPSysOrg gspSysOrg1 = sysOrgManager.addSysOrg(topVo);
                                deptpkMap.put(attribute, topVoId);
                            } else {
                                topVo = orgsByFilter.get(0);
                                topVoId = topVo.getId();
                            }

                            gspSysOrg.setParentId(topVoId);
                            gspSysOrg.setLayer(3);
                        }
                    } else {
                        // 查询是否有上级ID
                        GSPSysOrg sysParentOrg = sysOrgManager.getSysOrg(pkftDoc);
                        if (sysParentOrg != null) {
                            gspSysOrg.setParentId(pkftDoc);
                            gspSysOrg.setLayer(sysParentOrg.getLayer() + 1);
                        } else {
                            log.error("{}:{}:{}->{}", "未找到上级部门", deptlistname, pkDoc, pkftDoc);
                            continue;
                        }
                    }

                    // 更新信息
                    gspSysOrg.setLastModifiedTime(nowDate);
                    try {
                        if (isNew) {
                            GSPSysOrg gspSysOrg1 = sysOrgManager.addSysOrg(gspSysOrg);
                        } else {
                            sysOrgManager.modifySysOrg(gspSysOrg);
                        }
                    } catch (Exception e) {
                        log.error("{}:{}:{}", e.getMessage(), deptlistname, gspSysOrg.getId());
                    }

                }
                offset += limit;
            }
        }
        log.info("组织同步完成!");

        // String stopSql = "UPDATE GSPSYSORG t SET t.STATE = 0 WHERE t.LASTMODIFIEDTIME < TO_DATE('" + nowFormat + "','yyyy-MM-dd HH24:MI:SS') AND CREATOR = 'backendScheduler'";
        // bqlExecuter.executeBqlStatement(stopSql,new ArrayList<>());
    }

    public static String removeSpecialChars(String input) {
        if (input == null) {
            return null;
        }
        String SPECIAL_CHARS_REGEX = "[]~`!@#$%^&*()+=|\\}{:;',\"\\\\/?<>";

        // 使用正则表达式替换所有特殊符号为空
        return input.replaceAll("[" + Pattern.quote(SPECIAL_CHARS_REGEX) + "]", "");
    }


    public void getPerson(String ts) throws Exception {
        // 获取配置信息
        String selectUrl = "select cfgvalue as CV from SBSS_POST_OUTSEVE where NODE = 'perStUrl' and LABEL = 'url'";
        List<DynamicResultRow> resRows = bqlExecuter.executeSelectStatement(selectUrl, new ArrayList<>());
        if (resRows.isEmpty()) {
            throw new Exception("获取人员URL失败!!! 请检查 SBSS_POST_OUTSEVE 表中 NODE = 'perStUrl' 与 LABEL = 'url' 是否存在");
        }
        String url = resRows.get(0).get("CV").toString();

        // 判断是否初始化
        addAndUpdPerson(url);
    }

    public void addAndUpdPerson(String url) throws JsonProcessingException {
        log.info("开始人员同步!");
        int offset = 0;
        int limit = 600;
        int dataCount = limit;
        while (dataCount > 0) {
            String json = "{\n" +
                    "    \"limit\": " + limit + ",\n" +
                    "    \"offset\": " + offset + ",\n" +
                    "    \"orderBy\": [\n" +
                    "        {\n" +
                    "            \"name\": \"id\",\n" +
                    "            \"desc\": false\n" +
                    "        }\n" +
                    "    ]\n" +
                    "}";
            String respStr = HttpUtil.doPost(url, json);

            ObjectMapper jsonParser = new ObjectMapper();
            JsonNode jsonNode = jsonParser.readTree(respStr);
            JsonNode items = jsonNode.get("data").get("items");
            dataCount = items.size();
            for (JsonNode item : items) {
                String id = item.get("id").asText();
                String name = item.get("name").asText();
                String code = item.get("code").asText();
                String gender = item.get("gender").asText();
                String pk_deptdoc = item.get("pk_deptdoc").asText("");
                // 0 在职 2：解聘人员；3：离退人员；4：调离人员；5：其他人员
                String psnclscope = item.get("psnclscope").asText();

                User user = new User();
                user.setId(id);
                user.setName(name);
                user.setCode(code);
                user.setSex(gender.equals("男") ? "1" : "2");

                GSPSysOrg sysOrg = sysOrgManager.getSysOrg(pk_deptdoc);
                if (sysOrg != null) {
                    user.setSysOrgId(sysOrg.getId());
                }else {
                    user.setSysOrgId(topOrg.getId());
                }

                String dataBaseId = userManager.getUserIdByCode(code);
                if (dataBaseId != null) {
                    user.setId(dataBaseId);
                }
                User user1 = userManager.getUser(user.getId());

                try {
                    // 如果远程接口当前处于活跃状态
                    if (psnclscope.equals("0")){
                        // 如果用户在系统中存在
                        if (user1 != null) {
                            userManager.modifyUser(user);
                        } else {
                            user.setUserType(UserType.inner);
                            addUserByDefaultPwd(user);
                        }
                        userLimitManager.modifyUserState(user.getId(), UserState.using);
                    } else {
                        if (user1 != null) {
                            userLimitManager.modifyUserState(user.getId(), UserState.stop);
                        }
                    }
                }catch (Exception e){
                    log.error("{}:{}:{}", e.getMessage(),name,code);
                }
            }
            offset += limit;
        }
        log.info("人员同步完成!");
    }

    private void addUserByDefaultPwd(User user) {
        userManager.addUserWithPwd(user, "Cssc@" + user.getCode());
    }


    // 查询Log记录
    public String queryLog() {
        // 查询是否有Log记录
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00"));
        String selectSql = "select id,cfgvalue as CV from SBSS_POST_OUTSEVE where NODE = 'deptTs' and LABEL = 'ts'";
        List<DynamicResultRow> resRows = bqlExecuter.executeSelectStatement(selectSql, new ArrayList<>());
        if (!resRows.isEmpty()) {
            DynamicResultRow dynamicResultRow = resRows.get(0);
            return dynamicResultRow.get("CV").toString();
        } else {
            init = true;
            insetLog(nowTime);
            return nowTime;
        }
    }

    public void insetLog(String nowTime) {
        HashMap<String, Object> log = new HashMap<>();
        log.put("ID", UUID.randomUUID().toString());
        log.put("VERSION", LocalDateTime.now());
        log.put("CREATER", LocalDateTime.now());
        log.put("NODE", "deptTs");
        log.put("LABEL", "ts");
        log.put("CFGVALUE", nowTime);
        String sql = SQLUtil.insetSql("SBSS_POST_OUTSEVE", log);
        bqlExecuter.executeBqlStatement(sql, new ArrayList<>());
    }

    // 更新Log记录
    public void updateLog() {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:00"));
        String selectSql = "select id as ID ,cfgvalue as CV from SBSS_POST_OUTSEVE where NODE = 'deptTs' and LABEL = 'ts'";
        List<DynamicResultRow> resRows = bqlExecuter.executeSelectStatement(selectSql, new ArrayList<>());
        if (!resRows.isEmpty()) {
            DynamicResultRow dynamicResultRow = resRows.get(0);
            String id = dynamicResultRow.get("ID").toString();
            String updateSql = "update SBSS_POST_OUTSEVE set cfgvalue = '" + nowTime + "' where id = '" + id + "'";
            bqlExecuter.executeBqlStatement(updateSql, new ArrayList<>());
        } else {
            insetLog(nowTime);
        }
    }
}